using GameFrameWork;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;

namespace GameFrameWork
{

    [ExecuteInEditMode]
    [DisallowMultipleComponent]
    public class UIRectMesh : UIBaseMesh
    {
        readonly static Rect DEFAULT_RECT = new Rect(Vector2.zero, new Vector2(100, 100));

        [SerializeField] Rect rect = DEFAULT_RECT;

        Vector3[] vectors = new Vector3[4];


        public Rect MeshRect
        {
            get => rect;
            set
            {
                if (rect != value)
                {
                    rect = value;
                    SetVertexDirty();
                }
            }
        }

        protected override void OnModifyMesh(VertexHelper vh, ref Vector4 outBound, ref Vector4 outUV, ref Color outColor)
        {
            base.OnModifyMesh(vh, ref outBound, ref outUV, ref outColor);

            vh.Clear();
            {
                float delta_width = rect.width / 2;
                float delta_height = rect.height / 2;

                float delta_uv_w = outUV.z - outUV.x;
                float delta_uv_h = outUV.w - outUV.y;

                float delta_vec_w = outBound.z - outBound.x;
                float delta_vec_h = outBound.w - outBound.y;

                float tex_x, tex_y;
                vectors[0] = new Vector3(rect.x - delta_width, rect.y - delta_height);
                vectors[1] = new Vector3(rect.x + delta_width, rect.y - delta_height);
                vectors[2] = new Vector3(rect.x + delta_width, rect.y + delta_height);
                vectors[3] = new Vector3(rect.x - delta_width, rect.y + delta_height);

                for (int i = 0, length = vectors.Length; i < length; i++)
                {
                    UIVertex point = UIVertex.simpleVert;
                    point.position = vectors[i];

                    if (point.position.y > outBound.w)
                    {
                        point.position.y = outBound.w;
                    }

                    if (point.position.y < outBound.y)
                    {
                        point.position.y = outBound.y;
                    }

                    if (point.position.x < outBound.x)
                    {
                        point.position.x = outBound.x;
                    }

                    if (point.position.x > outBound.z)
                    {
                        point.position.x = outBound.z;
                    }

                    tex_x = (point.position.x - outBound.x) / delta_vec_w;
                    tex_y = (point.position.y - outBound.y) / delta_vec_h;

                    point.uv0.x = tex_x * delta_uv_w + outUV.x;
                    point.uv0.y = tex_y * delta_uv_h + outUV.y;

                    point.color = outColor;

                    vh.AddVert(point);
                }

                vh.AddTriangle(0, 2, 1);
                vh.AddTriangle(0, 3, 2);
            }
        }



        private void SetVertexDirty()
        {
            graphic?.SetVerticesDirty();
        }


#if UNITY_EDITOR
        protected override void OnValidate()
        {
            base.OnValidate();

            if (!Application.isPlaying)
                SetVertexDirty();
        }


        public new void OnDestroy()
        {
            if (!Application.isPlaying)
            {
                SetVertexDirty();
            }
        }

        protected override void Reset()
        {
            base.Reset();

            rect = DEFAULT_RECT;
            SetVertexDirty();
        }
#endif
    }
}

